package wiki.zimo.utils;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * 数据源工具类
 *
 * @author 子墨
 * @date 2018年5月24日 下午2:41:55
 */
public class DataSourceUtils {

    private static ComboPooledDataSource ds = new ComboPooledDataSource();
    private static ThreadLocal<Connection> tl = new ThreadLocal<>();

    /**
     * @auther: 子墨
     * @date: 2018/10/30 12:46
     * @describe: 获取数据源
     * @param: []
     * @return: javax.sql.DataSource
     * @version v1.0
     */
    public static DataSource getDataSource() {
        return ds;
    }

    /**
     * @auther: 子墨
     * @date: 2018/10/30 12:46
     * @describe: 从线程中获取连接
     * @param: []
     * @return: java.sql.Connection
     * @version v1.0
     */
    public static Connection getConnection() throws SQLException {
        Connection conn = tl.get();
        // 若是第一次获取 需要从池中获取一个连接,将这个连接和当前线程绑定
        if (conn == null) {
            conn = ds.getConnection();
            // 将这个连接和当前线程绑定
            tl.set(conn);
        }
        return conn;
    }


    /**
     * @auther: 子墨
     * @date: 2018/10/30 12:47
     * @describe: 关闭连接，释放资源
     * @param: [conn, st, rs]
     * @return: void
     * @version v1.0
     */
    public static void closeResource(Connection conn, Statement st, ResultSet rs) {
        closeResultSet(rs);
        closeStatement(st);
        closeConn(conn);
    }

    /**
     * @auther: 子墨
     * @date: 2018/10/30 12:47
     * @describe: 关闭连接
     * @param: [conn]
     * @return: void
     * @version v1.0
     */
    public static void closeConn(Connection conn) {
        if (conn != null) {
            try {
                conn.close();
                // 和当前线程解绑
                tl.remove();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }

    /**
     * @auther: 子墨
     * @date: 2018/10/30 12:48
     * @describe: 关闭Statement
     * @param: [st]
     * @return: void
     * @version v1.0
     */
    public static void closeStatement(Statement st) {
        if (st != null) {
            try {
                st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        st = null;
    }

    /**
     * @auther: 子墨
     * @date: 2018/10/30 12:49
     * @describe: 关闭ResultSet
     * @param: [rs]
     * @return: void
     * @version v1.0
     */
    public static void closeResultSet(ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        rs = null;
    }

    /**
     * @auther: 子墨
     * @date: 2018/10/30 12:50
     * @describe: 开启事物
     * @param: []
     * @return: void
     * @version v1.0
     */
    public static void beginTransaction() throws SQLException {
        // 获取连接
        Connection conn = getConnection();
        // 开始
        conn.setAutoCommit(false);
    }

    /**
     * @auther: 子墨
     * @date: 2018/10/30 12:50
     * @describe: 提交事物
     * @param: []
     * @return: void
     * @version v1.0
     */
    public static void commitTransaction() {
        try {
            // 获取连接
            Connection conn = getConnection();
            // 提交事务
            conn.commit();
            // 关闭且移除
            closeConn(conn);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * @auther: 子墨
     * @date: 2018/10/30 12:51
     * @describe: 回滚事务
     * @param: []
     * @return: void
     * @version v1.0
     */
    public static void rollbackAndClose() {
        try {
            // 获取连接
            Connection conn = getConnection();
            // 事务回滚
            conn.rollback();
            // 关闭且移除
            closeConn(conn);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
